<template>
  <div class="nodestyleset-modal">
    <el-config-provider :locale="zhCn">
      <!-- 节点样式设置 -->
      <div v-show="subjectStyle">
        <div class="style-block">
          <p class="set-title">文字</p>
          <div class="modal">
            <p>字体</p>
            <el-select
              v-model="fontFamily"
              placeholder="请选择字体"
              style="width: 200px"
              @change="handlerUpdateStyle($event, 'fontFamily')"
            >
              <el-option
                v-for="item in FONTFAMILYOPTIONS"
                :value="item.value"
                :key="item.value"
                :label="item.label">
                <span :style="{ 'font-family': item.value, 'line-height': '30px' }">{{ item.label }}</span>
              </el-option>
            </el-select>
          </div>
          <div class="modal">
            <div class="c">
              <p>字号</p>
              <el-select
                v-model="fontSize"
                placeholder="请选择"
                style="width: 100px"
                @change="handlerUpdateStyle($event, 'fontSize')"
              >
                <el-option v-for="item in FONTSIZEOPTIONS" :label="item.label" :value="item.value" :key="item.value"></el-option>
              </el-select>
            </div>
            <div class="c">
              <p>划线</p>
              <el-select
                v-model="textDecoration"
                placeholder="请选择"
                style="width: 100px"
                @change="handlerUpdateStyle($event, 'textDecoration')"
              >
                <el-option v-for="item in TEXTDECARATIONOPTIONS" :label="item.label" :value="item.value" :key="item.value"></el-option>
              </el-select>
            </div>
          </div>
          <div class="modal">
            <div class="c">
              <p>颜色</p>
              <el-color-picker
                :teleported="false"
                v-model="textColor"
                show-alpha
                color-format="hex"
                @active-change="handlerUpdateStyle($event, 'textColor')"
                @show="handleColorPickShow"
                @hide="handleColorPickHide" />
            </div>
            <div class="c">
              <div
                @click="handlerUpdateStyle(fontWeight === 'bold' ? 'normal' : 'bold', 'fontWeight')"
                title="加粗"
                class="font"
                :class="{ active: fontWeight === 'bold' }">
                <span class="ri-bold"></span>
              </div>
              <div
                @click="handlerUpdateStyle(fontStyle === 'italic' ? 'normal' : 'italic', 'fontStyle')"
                title="斜体"
                class="font"
                :class="{ active: fontStyle === 'italic' }">
                <span class="ri-italic"></span>
              </div>
            </div>
          </div>
          <div class="modal space-between">
            <div class="c" style="margin-right: 0;">
              <p>方向</p>
              <el-radio-group
                v-model="textDirection"
                @change="handlerUpdateStyle($event, 'textDirection')"
                size="small">
                <el-radio-button label="横向" value="hor">横向</el-radio-button>
                <el-radio-button label="竖向" value="ver">竖向</el-radio-button>
              </el-radio-group>
            </div>
            <div class="c">
              <p>对齐</p>
              <el-radio-group
                v-model="align"
                size="small"
                @change="handlerUpdateStyle($event, 'align')">
                <el-radio-button value="flex-start"><i class="ri-align-left"></i></el-radio-button>
                <el-radio-button value="center"><i class="ri-align-center"></i></el-radio-button>
                <el-radio-button value="flex-end"><i class="ri-align-right"></i></el-radio-button>
              </el-radio-group>
            </div>
          </div>
        </div>
        <div class="style-block">
          <p class="set-title">主题</p>
          <div class="modal">
            <div class="c">
              <p>填充</p>
              <el-color-picker
                :teleported="false"
                v-model="backgroundColor"
                show-alpha
                color-format="hex"
                @active-change="handlerUpdateStyle($event, 'backgroundColor')"
                @show="handleColorPickShow"
                @hide="handleColorPickHide" />
            </div>
          </div>
          <div class="modal">
            <div class="c">
              <p>形状</p>
              <el-popover placement="top" :show-arrow="false" popper-class="flex-dropdown-menu w-260">
                <template #reference>
                  <div class="edge-select-end-img">
                    <img :src="shapeImg" alt="">
                  </div>
                </template>
                <ul>
                  <li @click="handlerUpdateStyle(item.key, 'shape')" v-for="item in shapeList" :key="item.key">
                    <img style="height: 28px;" :src="require(`@/assets/images/xmind/shape/${item.key}.svg`)" alt="">
                  </li>
                </ul>
              </el-popover>
            </div>
            <div class="c">
              <p>最大宽度</p>
              <el-select
                v-model="maxWidth"
                placeholder="请选择"
                style="width: 160px"
                @change="handlerUpdateStyle($event, 'maxWidth')"
              >
                <el-option v-for="item in FONTMAXWIDTHOPTIONS" :label="item.label" :value="item.value" :key="item.value"></el-option>
              </el-select>
            </div>
          </div>
        </div>
        <div class="style-block">
          <p class="set-title">边框</p>
          <div class="modal">
            <div class="c">
              <p>颜色</p>
              <el-color-picker
                :teleported="false"
                v-model="strokeColor"
                show-alpha
                color-format="hex"
                @active-change="handlerUpdateStyle($event, 'strokeColor')"
                @show="handleColorPickShow"
                @hide="handleColorPickHide" />
            </div>
          </div>
          <div class="modal space-between">
            <div class="c">
              <p>样式</p>
              <el-select
                v-model="strokeStyle"
                placeholder="请选择"
                style="width: 100px"
                @change="handlerUpdateStyle($event, 'strokeStyle')"
              >
                <el-option v-for="item in STROKESTYLEOPTIONS" :label="item.label" :value="item.value" :key="item.value"></el-option>
              </el-select>
            </div>
            <div class="c">
              <p>宽度</p>
              <el-select
                v-model="strokeWidth"
                placeholder="请选择"
                style="width: 100px"
                @change="handlerUpdateStyle($event, 'strokeWidth')"
              >
                <el-option v-for="item in STROKEWIDTHOPTIONS" :label="item.label" :value="item.value" :key="item.value"></el-option>
              </el-select>
            </div>
          </div>
        </div>
        <div class="style-block">
          <p class="set-title">连线</p>
          <div class="modal space-between">
            <div class="c">
              <p>颜色</p>
              <el-color-picker
                :teleported="false"
                v-model="lineColor"
                show-alpha
                color-format="hex"
                @active-change="handlerUpdateStyle($event, 'lineColor')"
                @show="handleColorPickShow"
                @hide="handleColorPickHide" />
            </div>
            <div class="c">
              <p>分支</p>
              <el-popover placement="top" :show-arrow="false" popper-class="flex-dropdown-menu w-155">
                <template #reference>
                  <div class="edge-select-end-img" style="padding: 5px 8px;">
                    <img :src="lineStyleImg" alt="" style="width: 42px">
                  </div>
                </template>
                <ul>
                  <li @click="handlerUpdateStyle(item.value, 'branch')" v-for="item in lineStyleList" :key="item.value">
                    <img style="height: 22px;" :src="item.img" alt="">
                  </li>
                </ul>
              </el-popover>
            </div>
            <div class="c">
              <p>终点</p>
              <el-popover :disabled="isRoot" placement="top" :show-arrow="false" popper-class="flex-dropdown-menu w-180">
                <template #reference>
                  <div class="edge-select-end-img" :class="{ disabled: isRoot }">
                    <img :src="lineEndJoinImg" alt="">
                  </div>
                </template>
                  <ul>
                    <li @click="handlerUpdateStyle(item.value, 'lineEndJoin')" v-for="item in edgeJoinEndStyleList" :key="item.value">
                      <img style="height: 28px;" :src="item.img" alt="">
                    </li>
                  </ul>
              </el-popover>
            </div>
          </div>
          <div class="modal space-between">
            <div class="c w_108">
              <p>样式</p>
              <el-select
                v-model="dot"
                placeholder="请选择"
                @change="handlerUpdateStyle($event, 'dot')"
              >
                <el-option v-for="item in STROKESTYLEOPTIONS" :label="item.label" :value="item.value" :key="item.value"></el-option>
              </el-select>
            </div>
            <div class="c flex_1">
              <p>尺寸</p>
              <el-select
                v-model="lineWidth"
                placeholder="请选择"
                @change="handlerUpdateStyle($event, 'lineWidth')"
              >
              <el-option-group
                v-for="item in EDGELINESIZEOPTIONS.slice(0, isRoot ? 2 : 1)"
                :key="item.label"
                :label="item.label">
                <el-option
                  v-for="itemName in item.options"
                  :label=itemName.label
                  :key="itemName.value"
                  :value="itemName.value"></el-option>
              </el-option-group>
              </el-select>
            </div>
          </div>
        </div>
        <div class="style-block">
          <p class="set-title">边距</p>
          <div class="modal">
            <p>水平外边距</p>
            <div style="width: 200px">
              <el-input-number :disabled="mapGloabConfig.compact" v-model="horizontalOutter" :min="15" :max="200" @change="handlerUpdateStyle($event, 'horizontalOutter')">
              </el-input-number>
            </div>
          </div>
        </div>
      </div>
      <!-- 全局样式 -->
      <div class="gloab-subject-modal" v-show="!subjectStyle">
        <div class="style-block has-border">
          <div class="modal">
            <div class="c">
              <p class="fix-width">背景颜色</p>
              <el-color-picker
                :teleported="false"
                v-model="mapGloabConfig.backgroundColor"
                @active-change="handleMapBgUpdate"
                @show="handleColorPickShow"
                @hide="handleColorPickHide" />
            </div>
          </div>
        </div>
        <div class="style-block">
          <div class="modal">
            <p class="fix-width">全局字体</p>
            <el-select
              v-model="fontFamily"
              placeholder="请选择"
              style="width: 150px"
              @change="handlerUpdateStyle($event, 'fontFamily', true)"
            >
              <el-option
                v-for="item in FONTFAMILYOPTIONS"
                :value="item.value"
                :key="item.value"
                :label="item.label">
                <span :style="{ 'font-family': item.value, 'line-height': '30px' }">{{ item.label }}</span>
              </el-option>
            </el-select>
          </div>
          <div class="modal">
            <div class="c">
              <p class="fix-width">全局字号</p>
              <el-select
                v-model="fontSize"
                placeholder="请选择"
                style="width: 150px"
                @change="handlerUpdateStyle($event, 'fontSize', true)"
              >
                <el-option v-for="item in FONTSIZEOPTIONS" :label="item.label" :value="item.value" :key="item.value"></el-option>
              </el-select>
            </div>
          </div>
          <div class="modal">
            <p class="fix-width">最大宽度</p>
            <el-select
              @change="handlerUpdateStyle($event, 'maxWidth', true)"
              v-model="maxWidth"
              placeholder="请选择"
              style="width: 150px"
            >
              <el-option v-for="item in FONTMAXWIDTHOPTIONS" :label="item.label" :value="item.value" :key="item.value"></el-option>
            </el-select>
          </div>
          <div class="modal">
            <div class="c">
              <p class="fix-width">文字颜色</p>
              <el-color-picker
                :teleported="false"
                v-model="textColor"
                show-alpha
                color-format="hex"
                @active-change="handlerUpdateStyle($event, 'textColor', true)"
                @show="handleColorPickShow"
                @hide="handleColorPickHide" />
            </div>
            <div class="c">
              <div
                @click="handlerUpdateStyle(fontWeight === 'bold' ? 'normal' : 'bold', 'fontWeight', true)"
                title="加粗"
                class="font"
                :class="{ active: fontWeight === 'bold' }">
                <span class="ri-bold"></span>
              </div>
              <div
                @click="handlerUpdateStyle(fontStyle === 'italic' ? 'normal' : 'italic', 'fontStyle', true)"
                title="斜体"
                class="font"
                :class="{ active: fontStyle === 'italic' }">
                <span class="ri-italic"></span>
              </div>
            </div>
          </div>
          <div class="modal">
            <p class="fix-width">填充颜色</p>
            <el-color-picker
              :teleported="false"
              v-model="backgroundColor"
              show-alpha
              color-format="hex"
              @active-change="handlerUpdateStyle($event, 'backgroundColor', true)"
              @show="handleColorPickShow"
              @hide="handleColorPickHide"  />
          </div>
        </div>
        <div class="style-block">
          <p class="set-title">画布</p>
          <div class="modal" style="margin-top: 10px;">
            <el-checkbox v-model="mapGloabConfig.compact" label="紧凑型布局" size="large" />
          </div>
          <div class="modal" style="margin-top: 0px;">
            <el-checkbox v-model="mapGloabConfig.aligning" label="同级主题对齐" size="large" />
          </div>
          <div class="modal wrap" style="margin-top: 0px;">
            <el-checkbox v-model="mapGloabConfig.watermark.show" label="显示水印" size="large" />
            <el-input v-model="mapGloabConfig.watermark.text" style="width: 80%" placeholder="水印文字不能超过20个字符" :maxlength="20" size="default" @change="handleWaterTextChange"></el-input>
          </div>
        </div>
      </div>
    </el-config-provider>
  </div>
</template>

<script setup>
import { defineProps, reactive, watch, computed, toRefs } from 'vue'
import { ElConfigProvider } from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import {
  FONTFAMILYOPTIONS,
  FONTMAXWIDTHOPTIONS,
  FONTSIZEOPTIONS,
  STROKESTYLEOPTIONS,
  STROKEWIDTHOPTIONS,
  TEXTDECARATIONOPTIONS,
  EDGELINESIZEOPTIONS
} from '../config'
import mitter from '@/mitt'
import { shortcutKeydown, resetcutKeydown } from '../shortcut-key'
import shapeList from '../config/shape'

const props = defineProps({
  subjectStyle: {
    type: Object,
    default: () => null
  },
  isRoot: Boolean,
  gloabConfig: {
    type: Object,
    default: () => {
      return {}
    }
  },
  mapBackgroundColor: String
})

const lineStyleList = [
  { img: require('@/assets/images/xmind/line-shape/lineCurve.svg'), value: 'lineCurve' },
  { img: require('@/assets/images/xmind/line-shape/lineRoundedElbow.svg'), value: 'lineRoundedElbow' },
  { img: require('@/assets/images/xmind/line-shape/lineElbow.svg'), value: 'lineElbow' },
  { img: require('@/assets/images/xmind/line-shape/lineBight.svg'), value: 'lineBight' },
  { img: require('@/assets/images/xmind/line-shape/lineStraight.svg'), value: 'lineStraight' },
  { img: require('@/assets/images/xmind/line-shape/lineRoundedFold.svg'), value: 'lineRoundedFold' }
]

const edgeJoinEndStyleList = [
  { img: require('@/assets/images/xmind/arrow-none.svg'), value: 'arrow-none' },
  { img: require('@/assets/images/xmind/arrow-end-triangle.svg'), value: 'arrow-end-triangle' },
  { img: require('@/assets/images/xmind/arrow-end-diamond.svg'), value: 'arrow-end-diamond' },
  { img: require('@/assets/images/xmind/arrow-end-dot.svg'), value: 'arrow-end-dot' },
  { img: require('@/assets/images/xmind/arrow-end-doublearrow.svg'), value: 'arrow-end-doublearrow' },
  { img: require('@/assets/images/xmind/arrow-end-spearhead.svg'), value: 'arrow-end-spearhead' },
  { img: require('@/assets/images/xmind/arrow-end-square.svg'), value: 'arrow-end-square' },
  { img: require('@/assets/images/xmind/arrow-end-antiTriangle.svg'), value: 'arrow-end-antiTriangle' },
  { img: require('@/assets/images/xmind/arrow-end-attached.svg'), value: 'arrow-end-attached' }
]

const mapGloabConfig = reactive({
  compact: false,
  aligning: false,
  watermark: {
    text: '',
    show: false
  },
  backgroundColor: null
})

const styleObject = reactive({
  fontFamily: 'nevermind', // 字体
  fontSize: 12, // 字号
  fontWeight: 'normal', // 是否粗体
  fontStyle: 'normal', // 是否斜体
  textDecoration: 'none', // 划线
  textColor: null, // 文字颜色
  textDirection: 'hor', // 文本方向
  align: 'flex-start', // 对齐方向
  maxWidth: 500,
  strokeColor: null, // 边框颜色
  strokeStyle: null, // 边框样式
  strokeWidth: 0, // 边框宽度
  backgroundColor: null, // 背景色
  lineColor: null, // 线条颜色
  branch: null, // 连线样式
  lineWidth: null, // 连线尺寸
  lineEndJoin: null, // 连线终点连接样式
  dot: null,
  horizontalOutter: 22, // 水平外边距
  shape: 'default' // 主题形状
})

function handlerUpdateStyle (filedValue, filedName, gloab) {
  if ([
    'fontWeight',
    'fontStyle',
    'textColor',
    'strokeColor',
    'lineColor',
    'backgroundColor',
    'lineEndJoin',
    'shape',
    'branch'
  ].includes(filedName)) {
    styleObject[filedName] = filedValue
  }
  mitter.emit('update-subject-style', { filedValue, filedName, gloab })
}

const lineEndJoinImg = computed(() => {
  const t = edgeJoinEndStyleList.find(o => o.value === styleObject.lineEndJoin)
  return t?.img || require('@/assets/images/xmind/arrow-none.svg')
})

const shapeImg = computed(() => {
  const t = shapeList.find(o => o.key === styleObject.shape)
  return require(`@/assets/images/xmind/shape/${t?.key || 'default'}.svg`)
})

const lineStyleImg = computed(() => {
  const t = lineStyleList.find(o => o.value === styleObject.branch)
  return t?.img
})

function handleColorPickShow () {
  resetcutKeydown()
}

function handleColorPickHide () {
  shortcutKeydown()
}

watch(() => props.subjectStyle, newVal => {
  if (newVal) {
    Object.assign(styleObject, newVal)
  }
}, { deep: true })

watch(() => props.gloabConfig, () => {
  if (!props.gloabConfig) return
  const { compact = false, aligning = false, backgroundColor, watermark = { text: '', show: false } } = props.gloabConfig
  Object.assign(mapGloabConfig, {
    compact,
    aligning,
    watermark,
    backgroundColor
  })
}, { deep: true, immediate: true })

watch(() => props.mapBackgroundColor, newVal => {
  if (newVal) {
    mapGloabConfig.backgroundColor = newVal
  }
})

const {
  fontFamily,
  fontSize,
  fontWeight,
  fontStyle,
  textDecoration,
  textColor,
  textDirection,
  align,
  maxWidth,
  strokeColor,
  strokeStyle,
  strokeWidth,
  backgroundColor,
  lineColor,
  dot,
  horizontalOutter,
  lineWidth
} = toRefs(styleObject)

function handleMapBgUpdate (color) {
  mitter.emit('update-gloab-config-data', {
    ...mapGloabConfig,
    backgroundColor: color
  })
}

watch(() => [mapGloabConfig.aligning, mapGloabConfig.compact], () => {
  mitter.emit('update-gloab-config', mapGloabConfig)
}, { deep: true })

watch(() => mapGloabConfig.watermark.show, () => {
  mitter.emit('update-gloab-config-data', mapGloabConfig)
})

function handleWaterTextChange () {
  mitter.emit('update-gloab-config-data', mapGloabConfig)
}
</script>

<style lang="scss">
.nodestyleset-modal {
  .style-block {
    &:not(:last-child) {
      margin-bottom: 20px;
    }
    .set-title {
      font-size: 14px;
      color: #000;
      line-height: 24px;
      font-weight: 600;
    }
    .modal {
      display: flex;
      align-items: center;
      margin-top: 16px;
      &.wrap {
        flex-wrap: wrap;
      }
      &.space-between {
        flex-wrap: wrap;
        justify-content: space-between;
        .c {
          margin-bottom: 8px;
        }
      }
      .c {
        display: flex;
        align-items: center;
        &:not(:last-child) {
          margin-right: 15px;
        }
        .font {
          width: 50px;
          line-height: 28px;
          border-radius: 4px;
          text-align: center;

          margin-right: 12px;
          border: 1px solid #f1f1f1;
          &.active {
            background-color: #eee;
          }
          span {
            font-size: 18px;
            vertical-align: middle;
            color: #2c3e50;
          }
        }
        .edge-select-end-img {
          display: flex;
          background-color: #eee;
          padding: 4px 12px;
          border-radius: 4px;

          &.disabled {
            cursor: not-allowed;
            opacity: 0.6;
          }
          img {
            width: 24px;
          }
        }
        &.w_108 {
          width: 108px;
        }
        &.flex_1 {
          flex: 1;
        }
      }
      p {
        font-size: 12px;
        margin-right: 8px;
        color: #4c4c4c;
        flex-shrink: 0;
        &.fix-width {
          width: 50px;
          text-align-last: justify;
        }
      }
    }
    &.has-border {
      padding-bottom: 16px;
      position: relative;
      &::after {
        content: "";
        position: absolute;
        left: -20px;
        right: -20px;
        bottom: 0;
        height: 1px;
        background-color: #f1f1f1;
      }
    }
  }
}
</style>
